package com.jdkreader.concurent.forkjoin;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.RecursiveTask;

/**
 * 统计单词的出现次数
 *
 * @author zhaoyiwu
 * @create 2018-03-12 14:34
 * http://www.oracle.com/technetwork/cn/articles/java/fork-join-422606-zhs.html
 **/
public class WordCount {



    String[] wordsIn(String line) {
        return line.trim().split("(\\s|\\p{Punct})+");
    }

    Long occurrencesCount(Document document, String searchedWord) {
        long count = 0;
        for (String line : document.getLines()) {
            for (String word : wordsIn(line)) {
                if (searchedWord.equals(word)) {
                    count = count + 1;
                }
            }
        }
        return count;
    }

    Long countOccurrencesOnSingleThread(Folder folder, String searchedWord) {
        long count = 0;
        for (Folder subFolder : folder.getSubFolders()) {
            count = count + countOccurrencesOnSingleThread(subFolder, searchedWord);
        }
        for (Document document : folder.getDocuments()) {
            count = count + occurrencesCount(document, searchedWord);
        }
        return count;
    }


    /**
     * 计算单词在文档中的出现次数
     */
    class DocumentSearchTask extends RecursiveTask<Long> {
        private final Document document;
        private final String searchedWord;

        DocumentSearchTask(Document document, String searchedWord) {
            super();
            this.document = document;
            this.searchedWord = searchedWord;
        }

        @Override
        protected Long compute() {
            return occurrencesCount(document, searchedWord);
        }
    }

    class FolderSearchTask extends RecursiveTask<Long>{

        private final Folder folder;
        private final String searchedWord;


        public FolderSearchTask(Folder folder, String searchedWord) {
            this.folder = folder;
            this.searchedWord = searchedWord;
        }

        @Override
        protected Long compute() {

            Long count=0L;

            List<RecursiveTask<Long>> forks=new LinkedList<RecursiveTask<Long>>();

            for(Folder subFolder:folder.getSubFolders()){

                FolderSearchTask task=new FolderSearchTask(subFolder,searchedWord);
                //将任务添加到统计列表
                forks.add(task);
                //执行搜索任务
                task.fork();
            }

            for(Document document:folder.getDocuments()){

                DocumentSearchTask task=new DocumentSearchTask(document,searchedWord);
                //将任务添加到统计列表
                forks.add(task);
                //执行搜索任务
                task.fork();
            }

            //join 汇总任务结果
            for(RecursiveTask<Long> task: forks){
                count+=task.join();
            }

            return count;
        }
    }


    public static void main(String[] args) throws IOException {

        WordCount wordCounter=new WordCount();

        File file=new File("");

        Folder folder = Folder.fromDirectory(file);

        String searchWord="";

        System.out.println(wordCounter.countOccurrencesOnSingleThread(folder, searchWord));
    }



}
